package com.greenold.check.service.impl;

import cn.hutool.core.date.DateUtil;
import com.greenold.approvalRecord.domain.ApprovalRecord;
import com.greenold.approvalRecord.mapper.ApprovalRecordMapper;
import com.greenold.check.domain.Checkin;
import com.greenold.check.domain.Dto.CheckInConfigDto;
import com.greenold.check.domain.Dto.CheckinDto;
import com.greenold.check.domain.Dto.ContractDto;
import com.greenold.check.domain.Vo.CheckinVo;
import com.greenold.check.mapper.CheckinMapper;
import com.greenold.check.service.ICheckinService;
import com.greenold.checkInConfig.domain.CheckinConfig;
import com.greenold.checkInConfig.mapper.CheckinConfigMapper;
import com.greenold.commen.domain.Dto.ElderDto;
import com.greenold.commen.domain.Elder;
import com.greenold.commen.mapper.ElderMapper;
import com.greenold.commen.service.WorkFlowServie;
import com.greenold.common.core.domain.AjaxResult;
import com.greenold.common.core.domain.entity.SysUser;
import com.greenold.common.utils.DateUtils;
import com.greenold.common.utils.SecurityUtils;
import com.greenold.residing.domain.Contract;
import com.greenold.residing.mapper.BedMapper;
import com.greenold.residing.mapper.ContractMapper;
import com.greenold.service.mapper.CareLevelMapper;
import com.greenold.system.mapper.SysUserMapper;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.util.CollectionUtil;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import static java.util.stream.Collectors.toList;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 入住办理Service业务层处理
 *
 * @author ruoyi
 * @date 2025-10-13
 */
@Service
public class CheckinServiceImpl implements ICheckinService
{
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private CheckinMapper checkinMapper;
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private ApprovalRecordMapper approvalRecordMapper;
    @Autowired
    private WorkFlowServie workflowServie;
    @Autowired
    private CheckinConfigMapper checkinConfigMapper;
    @Autowired
    private ContractMapper contractMapper;
    @Autowired
    private CareLevelMapper careLevelMapper;
    @Autowired
    private BedMapper bedMapper;
    public Map<String, Object> setVariables(Checkin checkin)
    {
        Map<String, Object> variables = new HashMap<>();
        //标题
        variables.put("processTitle",checkin.getTitle());
        //申请人姓名
        variables.put("assignee0Name",checkin.getApplicant());
        //申请时间
        variables.put("applicationTime", DateUtil.date());
        //申请入住-养老顾问
        variables.put("assignee0",checkin.getApplicantId());
        //入住评估-护理主管
        variables.put("assignee1",1);
        //审核-副院长
        variables.put("assignee2",1);
        //入住选配-养老顾问
        variables.put("assignee3",checkin.getApplicantId());
        //签约-法务
        variables.put("assignee4",1);
        //业务类型 单据类别
        variables.put("processType",3);
        //流程类型code
        variables.put("processCode",checkin.getCode());

        //流程状态 1 申请中 2已通过 3已关闭
        return variables;
    }

    /**
     * 查询入住办理
     *
     * @param id 入住办理主键
     * @return 入住办理
     */
    @Override
    public Checkin selectCheckinById(String id)
    {
        return checkinMapper.selectCheckinById(id);
    }

    @Override
    public CheckinDto selectCheckinDtoById(String Id) {

        return checkinMapper.selectCheckinDtoById(Id);
    }
    /**
     * 查询入住办理列表
     *
     * @param checkin 入住办理
     * @return 入住办理
     */
    @Override
    public List<Checkin> selectCheckinList(Checkin checkin)
    {
        return checkinMapper.selectCheckinList(checkin);
    }
    /*
    *
    * 获取入住列表Dto
    * @param checkinDto 入住Dto
    * @return 入住Dto集合
    *
    * */
    @Override
    public List<CheckinDto> selectCheckinDtoList(CheckinDto checkinDto) {
        checkinDto.setApprovalStatus("1");
        return checkinMapper.selectCheckinDtoList(checkinDto);
    }

    /**
     * 新增入住办理
     *
     * @param checkinVo 入住办理
     * @return 结果
     */
    @Override
    public int insertCheckin(CheckinVo checkinVo)
    {
        Elder elder = checkinVo.getElder();
        elderMapper.insertElder( elder);
        checkinVo.setElderId(elder.getId());

        return checkinMapper.insertCheckin((Checkin)checkinVo);
    }

    /**
     * 修改入住办理
     *
     * @param checkin 入住办理
     * @return 结果
     */
    @Override
    public int updateCheckin(Checkin checkin)
    {
        return checkinMapper.updateCheckin(checkin);
    }

    /**
     * 批量删除入住办理
     *
     * @param ids 需要删除的入住办理主键
     * @return 结果
     */
    @Override
    public int deleteCheckinByIds(String[] ids)
    {
        return checkinMapper.deleteCheckinByIds(ids);
    }

    /**
     * 删除入住办理信息
     *
     * @param id 入住办理主键
     * @return 结果
     */
    @Override
    public int deleteCheckinById(String id)
    {
        return checkinMapper.deleteCheckinById(id);
    }
    @Override
    public AjaxResult create(Elder elder) {
        //1验证状态 如果老人发起过申请则不能再次发起
        Elder elder1 = elderMapper.selectElderByIdCard(elder.getIdCard());
        if(null!=elder1)
        {
            return AjaxResult.error("该老人已入住");
        }
        if ("男".equals(elder.getGender())) {
            elder.setGender("1");
        } else if ("女".equals(elder.getGender())) {
            elder.setGender("2");
        }
        //2保存老人信息
        elderMapper.insertElder(elder);
        //3保存入住信息
        Checkin checkin = new Checkin();
        checkin.setCode("SQ" + UUID.randomUUID().toString());
        checkin.setTitle(elder.getName()+"的入住申请");
        checkin.setElderId(elder.getId());
        //业务id
        String userId = SecurityUtils.getUserId().toString();
        SysUser user = sysUserMapper.selectUserById(Long.valueOf(userId));
        checkin.setConsultant(user.getUserName());
        //入住时间
        //原因
        checkin.setApplicant(user.getUserName());
        checkin.setDepartmentCode(user.getDept().getDeptName());
        checkin.setApplicantId(String.valueOf(user.getUserId()));
        //流程状态
        checkin.setProcessStatus("0");
        //审批状态 1 申请中 2已通过 3已关闭
        checkin.setApprovalStatus("1");
        checkin.setCreatedAt(DateUtils.getNowDate());
        checkinMapper.insertCheckin(checkin);
        //4准备流程变量
        Map<String,Object> variables = setVariables(checkin);
        //5启动流程实例，并且自动完成首节点
        //业务相关数据、登录用户相关数据、processDefineKey(checkIn)、首节点是否自动执行
        String processInstanceId =workflowServie.startProcess(checkin.getId(),user,"checkIn",variables,true);
        // 将流程实例ID保存到入住表
        checkin.setBusinessId(processInstanceId);
        checkinMapper.updateCheckin(checkin);
        // 获取下一个任务和下一个审批人
        Task nextTask = workflowServie.getNextTask(processInstanceId);
        SysUser nextUser = workflowServie.getNextAssignee(processInstanceId);
        //6保存审核记录
        ApprovalRecord approvalRecord = new ApprovalRecord();
        approvalRecord.setBusinessId(checkin.getBusinessId());      // 业务id（入住申请id）
        approvalRecord.setApprovalOpinion("发起入住申请");   // 审批意见
        approvalRecord.setApprovalType("3");                  // 审批类型(1:退住,2:请假,3:入住)
        approvalRecord.setApproverId(user.getUserId().toString());     // 审批人id（养老顾问）
        approvalRecord.setApproverName(user.getUserName()); // 审批人名称
        approvalRecord.setApproverRole("养老顾问");          // 审批人角色
        approvalRecord.setCurrentStep("申请入住");            // 当前步骤
        approvalRecord.setApprovalStatus("1");              // 审核状态(1:通过,2:拒绝,3:驳回,4:撤回,5:撤销)
        approvalRecord.setApprovalStep("1");                  // 审核步骤（第1步）
        approvalRecord.setProcessType("1");                   // 流程类型（3表示入住）
        approvalRecord.setCreatedBy(user.getUserId().toString());
        if (nextUser != null) {
            approvalRecord.setNextApproverId(nextUser.getUserId().toString());
            approvalRecord.setNextApproverName(nextUser.getUserName());
            approvalRecord.setNextApproverRole("护理主管");
            approvalRecord.setNextStep(nextTask.getName());
        } else {
            approvalRecord.setNextApproverId(null);
            approvalRecord.setNextApproverName("流程结束");
            approvalRecord.setNextApproverRole(null);
            approvalRecord.setNextStep("结束");
        }
        approvalRecordMapper.insertApprovalRecord(approvalRecord);
        return AjaxResult.success("申请入住成功，等待下一步");
    }
    //简单回显
    @Override
    public AjaxResult getElderInfo(String bussinessId){
        Elder elder = elderMapper.selectElderByBussinessId(bussinessId);
        if(elder== null)
        {
            return AjaxResult.error("未找到该老人信息");
        }
        return AjaxResult.success(elder);
    }
    //护理主管评估
    @Override
    public AjaxResult review( Map<String, Object> data){
        String userId = SecurityUtils.getUserId().toString();
        // 获取传入的参数
        String taskId = data.get("taskId").toString();
        String processInstanceId = data.get("processInstanceId").toString();
        Checkin checkin = checkinMapper.selectCheckinByBusinessId(processInstanceId);
        checkin.setProcessStatus("1");
        checkinMapper.updateCheckin(checkin);
        Map<String, Object> elderData = (Map<String, Object>) data.get("elder");
        ObjectMapper objectMapper = new ObjectMapper();
        // 更新老人信息
        Elder elder = elderMapper.selectElderByBussinessId(processInstanceId);
        // 获取评估数据并安全转换
        Object healthAssessmentObj = elderData.get("healthAssessment");
        if (healthAssessmentObj != null) {
            try {
                String healthAssessmentJson;
                if (healthAssessmentObj instanceof String) {
                    healthAssessmentJson = (String) healthAssessmentObj;
                } else {
                    // 转为 JSON 字符串
                    healthAssessmentJson = objectMapper.writeValueAsString(healthAssessmentObj);
                }
                elder.setHealthAssessment(healthAssessmentJson);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                // 出错时可以记录日志或赋值为空
                elder.setHealthAssessment(null);
            }
        }
        // 能力评估
        Object abilityAssessmentObj = elderData.get("abilityAssessment");
        if (abilityAssessmentObj != null) {
            try {
                String abilityAssessmentJson;
                if (abilityAssessmentObj instanceof String) {
                    abilityAssessmentJson = (String) abilityAssessmentObj;
                } else {
                    abilityAssessmentJson = objectMapper.writeValueAsString(abilityAssessmentObj);
                }
                elder.setAbilityAssessment(abilityAssessmentJson);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                elder.setAbilityAssessment(null);
            }
        }
        // 评估报告
        Object assessmentReportObj = elderData.get("assessmentReport");
        if (assessmentReportObj != null) {
            try {
                String assessmentReportJson;
                if (assessmentReportObj instanceof String) {
                    assessmentReportJson = (String) assessmentReportObj;
                } else {
                    assessmentReportJson = objectMapper.writeValueAsString(assessmentReportObj);
                }
                elder.setAssessmentReport(assessmentReportJson);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                elder.setAssessmentReport(null);
            }
        }
        elderMapper.updateElder(elder);
        // 完成当前任务
        workflowServie.completeTask(taskId,"1");
        SysUser nextAssignee = workflowServie.getNextAssignee(processInstanceId);
        Task nextTask = workflowServie.getNextTask(processInstanceId);
        ApprovalRecord approvalRecord = new ApprovalRecord();
        approvalRecord.setBusinessId(processInstanceId);
        approvalRecord.setApprovalOpinion("同意");
        approvalRecord.setApprovalType("3");
        approvalRecord.setApproverId(userId);
        approvalRecord.setApproverName(SecurityUtils.getUsername());
        approvalRecord.setApproverRole("护理主管");
        approvalRecord.setApprovalStep("2");
        approvalRecord.setCurrentStep("入住配置完成");
        approvalRecord.setNextStep(nextTask.getName());
        approvalRecord.setApprovalStatus("1");
//        approvalRecord.setApprovalStep("4");
        approvalRecordMapper.insertApprovalRecord(approvalRecord);
        // 4️⃣ （可选）更新入住表状态、添加审批记录等
        return AjaxResult.success("护理评估已完成等待下一步");
    }
    //副院长审批
    @Override
    public AjaxResult submit(String businessId, String message, String taskId, Integer shenHE){
        Checkin checkin = checkinMapper.selectCheckinByBusinessId(businessId);
        if(checkin == null) return AjaxResult.error("入住申请不存在");
        String userId = SecurityUtils.getUserId() != null ? SecurityUtils.getUserId().toString() : "unknown";
        String username = SecurityUtils.getUsername() != null ? SecurityUtils.getUsername() : "unknown";
        ApprovalRecord approvalRecord = new ApprovalRecord();
        approvalRecord.setBusinessId(businessId);
        approvalRecord.setApprovalOpinion(message);
        approvalRecord.setApprovalType("3");
        approvalRecord.setApproverId(userId);
        approvalRecord.setApproverName(username);
        approvalRecord.setApproverRole("副院长");
        approvalRecord.setCurrentStep("副院长审批");
        approvalRecord.setApprovalStep("3");
        approvalRecord.setProcessType("1");

        if(shenHE == 1){ // 审批通过
            checkin.setProcessStatus("1");
            checkin.setApprovalStatus("1");
            checkinMapper.updateCheckin(checkin);
            workflowServie.completeTask(taskId, "1");
            Task nextTask = workflowServie.getNextTask(businessId);
            SysUser nextAssignee = workflowServie.getNextAssignee(businessId);
            if (nextAssignee != null && nextTask != null) {
                approvalRecord.setNextApproverId(nextAssignee.getUserId().toString());
                approvalRecord.setNextApproverName(nextAssignee.getUserName());
                approvalRecord.setNextApproverRole("养老顾问");
                approvalRecord.setNextStep(nextTask.getName());
            }
            approvalRecord.setApprovalStatus("1");
            approvalRecordMapper.insertApprovalRecord(approvalRecord);
            return AjaxResult.success("副院长审批成功，等待下一步");
        } else { // 审批拒绝或驳回
            checkin.setProcessStatus("2");
            checkin.setApprovalStatus("2");
            checkinMapper.updateCheckin(checkin);
            workflowServie.completeTask(taskId, "2");
            approvalRecord.setNextApproverId(null);
            approvalRecord.setNextApproverName(null);
            approvalRecord.setNextApproverRole(null);
            approvalRecord.setNextStep(null);
            approvalRecord.setApprovalStatus("2");
            approvalRecordMapper.insertApprovalRecord(approvalRecord);
            return AjaxResult.success("审批已拒绝");
        }
    }
    //养老顾问入住配置
    @Override
    public AjaxResult checkInConfig( CheckInConfigDto checkInConfigDto){
        String userId = SecurityUtils.getUserId().toString();
        SysUser user = sysUserMapper.selectUserById(Long.valueOf(userId));
        String bussinessId = checkInConfigDto.getBussinessId();
        String taskId = checkInConfigDto.getTaskId();
        workflowServie.completeTask(taskId,"1");
        Checkin checkin = checkinMapper.selectCheckinByBusinessId(bussinessId);
        checkin.setCheckinTime(checkInConfigDto.getStartTime());
        CheckinConfig checkInConfig = new CheckinConfig();
        checkInConfig.setElderId(checkin.getElderId());
        checkInConfig.setStartTime(checkInConfigDto.getStartTime());
        checkInConfig.setEndTime(checkInConfigDto.getEndTime());
        checkInConfig.setCareLevelId(checkInConfigDto.getCareLevelId());
        checkInConfig.setBedNo(checkInConfigDto.getBedNo());
        checkInConfig.setFeeStartTime(checkInConfigDto.getFeeStartTime());
        checkInConfig.setFeeEndTime(checkInConfigDto.getFeeEndTime());
        checkInConfig.setDeposit(checkInConfigDto.getDeposit());
        checkInConfig.setCareFee(checkInConfigDto.getCareFee());
        checkInConfig.setBedFee(checkInConfigDto.getBedFee());
        checkInConfig.setOtherFee(checkInConfigDto.getOtherFee());
        checkInConfig.setInsurancePay(checkInConfigDto.getInsurancePay());
        checkInConfig.setGovSubsidy(checkInConfigDto.getGovSubsidy());
        checkinConfigMapper.insertCheckinConfig(checkInConfig);
        Task nextTask = workflowServie.getNextTask(bussinessId);
        SysUser nextAssignee = workflowServie.getNextAssignee(bussinessId);
        ApprovalRecord approvalRecord = new ApprovalRecord();
        approvalRecord.setBusinessId(checkin.getBusinessId());      // 业务id（入住申请id）
        approvalRecord.setApprovalOpinion("同意");   // 审批意见
        approvalRecord.setApprovalType("3");                  // 审批类型(1:退住,2:请假,3:入住)
        approvalRecord.setApproverId(user.getUserId().toString());     // 审批人id（养老顾问）
        approvalRecord.setApproverName(user.getUserName()); // 审批人名称
        approvalRecord.setApproverRole("养老顾问");          // 审批人角色
        approvalRecord.setCurrentStep("养老顾问入住配置");            // 当前步骤
        approvalRecord.setApprovalStatus("1");              // 审核状态(1:通过,2:拒绝,3:驳回,4:撤回,5:撤销)
        approvalRecord.setApprovalStep("4");                  // 审核步骤（第1步）
        approvalRecord.setProcessType("1");                   // 流程类型（3表示入住）
        approvalRecord.setCreatedBy(userId);
        approvalRecord.setExtend2(bussinessId);                  // 流程实例ID
        if (nextAssignee != null) {
            approvalRecord.setNextApproverId(nextAssignee.getUserId().toString());
            approvalRecord.setNextApproverName(nextAssignee.getUserName());
            approvalRecord.setNextApproverRole("法务人员");
            approvalRecord.setNextStep(nextTask.getName());
        } else {
            approvalRecord.setNextApproverId(null);
            approvalRecord.setNextApproverName("流程结束");
            approvalRecord.setNextApproverRole(null);
            approvalRecord.setNextStep("结束");
        }
        approvalRecordMapper.insertApprovalRecord(approvalRecord);

        return AjaxResult.success("入住配置成功等待下一步");
    }
    //法务人员签约办理
    @Override
    public AjaxResult sign(ContractDto contractDto){
        String userId = SecurityUtils.getUserId().toString();
        SysUser user = sysUserMapper.selectUserById(Long.valueOf(userId));
        String bussinessId = contractDto.getBussinessId();
        workflowServie.completeTask(contractDto.getTaskId(),"1");
        Checkin checkin = checkinMapper.selectCheckinByBusinessId(bussinessId);
        Elder elder = elderMapper.selectElderById(checkin.getElderId());
        Contract contract = new Contract();
        contract.setContractNo(contractDto.getContractNo());
        contract.setContractName(contractDto.getContractName());
        contract.setAgreementUrl(contractDto.getAgreementUrl());
        contract.setElderId(elder.getId());
        contract.setElderName(elder.getName());
        contract.setElderIdCard(elder.getIdCard());
        contract.setPartyCName(contractDto.getPartyCName());
        contract.setStartTime(contractDto.getStartTime());
        contract.setEndTime(contractDto.getEndTime());
        contract.setCreatedBy(user.getUserId().toString());
//        contract.setCreatedAt(new Date());
        contract.setCheckinNo(checkin.getCode());
        contract.setSignDate(contractDto.getStartTime());
        contractMapper.insertContract(contract);
        ApprovalRecord approvalRecord = new ApprovalRecord();
        approvalRecord.setBusinessId(checkin.getBusinessId());
        approvalRecord.setApprovalOpinion("同意");
        approvalRecord.setApprovalType("3");
        approvalRecord.setApproverId(user.getUserId().toString());
        approvalRecord.setApproverName(user.getUserName());
        approvalRecord.setApproverRole("法务人员");
        approvalRecord.setCurrentStep("签约办理");
        approvalRecord.setNextStep(null);
        approvalRecord.setApprovalStatus("1");
        approvalRecord.setApprovalStep("5");
        approvalRecord.setProcessType("1");
        approvalRecord.setCreatedBy(user.getUserName());
        approvalRecord.setCreatedAt(new Date());
        approvalRecordMapper.insertApprovalRecord(approvalRecord);

        return AjaxResult.success("签约办理成功");
    }
    //获取入职配置的护理等级列表和床位号列表
    @Override
    public AjaxResult getCareLevelAndBedList(){
        Map<String,Object> map = new HashMap<>();
        map.put("careLevelList",careLevelMapper.getAllCareLevelIds());
        map.put("bedList",bedMapper.selectBedCodeList());
        return AjaxResult.success(map);
    }
}

